/*
 * Copyright (C) 2008 Mo Chen <withinsea@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
(function ($) {
	
	$.extend({
		
		oo: {
			
			claz: function (constructor, overrides) {
				return $.oo.extendClaz(Object, constructor, overrides);
			},
			
			extendClaz: function (base, constructor, overrides) {
				base = base || Object;
				overrides = (constructor instanceof Function ? overrides : constructor) || {};
				constructor = constructor instanceof Function ? constructor : function () {
					base.apply(obj, arguments);
				};
				var standin = function () {};
				standin.prototype = base.prototype;
				var claz = (!$.oo.claz.WRAP_CONSTRUCTOR) ? constructor : function () {
					var obj = this;
					this.supr = function () { base.apply(obj, arguments); };
					if ($.oo.claz.SUPER_CONSTRUCTOR && (""+constructor).indexOf("this.supr(") < 0) {
						base.apply(obj);
					}
					constructor.apply(obj, arguments);
					delete obj.supr;
				};
				claz.prototype = $.extend(new standin(), overrides);
				if ($.oo.claz.FAKE_CONSTRUCTOR_PROP) {
					claz.prototype.constructor = claz;
				}
				return claz;
			},
			
			instantiate: function (claz) { // type, arg1, arg2...
				var standin = function () {};
				standin.prototype = claz.prototype;
				var obj = new standin();
				claz.apply(obj, Array.prototype.slice.apply(arguments, [1]));
				return obj;
			},
			
			proto: function (claz, prototype) {
				if (prototype === undefined) {
					return claz.prototype;
				} else {
					claz.prototype = prototype;
					return claz;
				}
			},
			
			propNames: function (obj) {
				var names = [];
				for (var name in obj) {
					names.push(name);
				}
				return names;
			},
			
			prop: function (obj, name, value) {
				if (typeof name == "string") {
					if (value === undefined) {
						return obj[name];
					} else {
						obj[name] = value;
						return obj;
					}
				} else {
					return $.extend(obj, name || {});
				}
			},
			
			deleteProp: function (obj, name) {	// obj, name1, name2...
				for (var i=1; i<arguments.length; i++) {
					delete obj[arguments[i]];
				}
				return obj;
			}
			
		}
		
	});
	
	$.extend($.oo.claz, {
		
		WRAP_CONSTRUCTOR: false,
		SUPER_CONSTRUCTOR: false,
		FAKE_CONSTRUCTOR_PROP: false
	});
	
}) (jQuery);
